package com.github.xzb617.adm.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.xzb617.adm.service.UserService;
import com.github.xzb617.domain.common.AjaxResponse;
import com.github.xzb617.domain.common.Page;
import com.github.xzb617.domain.common.PageData;
import com.github.xzb617.domain.common.PageTextCondition;
import com.github.xzb617.domain.dto.ModifySelfPwdDTO;
import com.github.xzb617.domain.dto.UserDTO;
import com.github.xzb617.domain.entity.User;
import com.github.xzb617.domain.vo.UserVO;
import com.github.xzb617.logs.OptLogger;
import com.github.xzb617.security.SubjectHolder;
import com.github.xzb617.security.perms.CheckRole;
import com.github.xzb617.security.perms.Role;
import com.github.xzb617.valid.group.Insert;
import com.github.xzb617.valid.group.Update;
import com.github.xzb617.valid.passy.PasswordChecker;
import com.github.xzb617.valid.passy.PasswordComplexity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.ValidationException;
import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * 用户管理入口
 * @author xzb617
 * @version 1
 */
@Validated
@RestController
@RequestMapping("/user")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    /**
     * 查询用户列表（分页）
     * @param condition 查询条件
     * @return AjaxResponse
     */
    @GetMapping("/getList")
    public AjaxResponse getList(PageTextCondition condition) {
        PageHelper.startPage(condition.getPageNum(), condition.getPageSize());
        List<User> details = this.userService.getList(condition);
        PageInfo<User> pageInfo = new PageInfo<>(details);
        PageData<UserVO> pageData = Page.toData(pageInfo, UserVO.class);
        return AjaxResponse.success().message("查询成功").data(pageData);
    }

    /**
     * 创建用户
     * @param dto 用户参数
     * @return AjaxResponse
     */
    @OptLogger(desc = "创建用户")
    @CheckRole(role = Role.SA)
    @PostMapping("/save")
    public AjaxResponse save(@RequestBody @Validated({Insert.class}) UserDTO dto) {
        this.userService.save(dto);
        return AjaxResponse.success().message("创建成功");
    }

    /**
     * 更新用户
     * @param dto 用户参数
     * @return AjaxResponse
     */
    @OptLogger(desc = "更新用户")
    @CheckRole(role = Role.SA)
    @PutMapping("/update")
    public AjaxResponse update(@RequestBody @Validated({Update.class}) UserDTO dto) {
        this.userService.update(dto);
        return AjaxResponse.success().message("更新成功");
    }

    /**
     * 删除用户
     * @param id 用户编号
     * @return AjaxResponse
     */
    @OptLogger(desc = "删除用户")
    @CheckRole(role = Role.SA)
    @DeleteMapping("/deleteById")
    public AjaxResponse deleteById(@NotNull(message = "用户编号不能为空") Integer id) {
        this.userService.deleteById(id);
        return AjaxResponse.success().message("删除成功");
    }

    /**
     * 重置用户密码
     * @param id 用户编号
     * @return AjaxResponse
     */
    @OptLogger(desc = "重置用户密码")
    @CheckRole(role = Role.SA)
    @GetMapping("/resetPwd")
    public AjaxResponse resetPwd(@NotNull(message = "用户编号不能为空") Integer id) {
        this.userService.resetPwd(id);
        return AjaxResponse.success().message("重置成功");
    }

    /**
     * 修改个人资料
     * @param dto 用户参数
     * @return AjaxResponse
     */
    @OptLogger(desc = "修改个人资料")
    @PutMapping("/modifySelf")
    public AjaxResponse modifySelf(@RequestBody UserDTO dto) {
        Integer uid = SubjectHolder.getContext().getUserId();
        dto.setId(uid);
        this.userService.update(dto);
        return AjaxResponse.success().message("修改成功");
    }

    /**
     * 修改个人密码
     * @param dto 新旧密码参数
     * @return AjaxResponse
     */
    @OptLogger(desc = "修改个人密码", shieldArgs = true)
    @PutMapping("/modifySelfPwd")
    public AjaxResponse modifySelfPwd(@RequestBody ModifySelfPwdDTO dto) {
        // 校验重复
        if (!dto.getNewPassword().equals(dto.getRepPassword())) {
            throw new ValidationException("新密码与确认密码不一致");
        }
        if (dto.getOldPassword().equals(dto.getNewPassword())) {
            throw new ValidationException("新密码与旧密码重复");
        }
        // 校验强度
        PasswordComplexity medium = PasswordComplexity.MEDIUM;
        PasswordChecker.valid(dto.getNewPassword(), medium, medium.getErrorMessage());
        // 修改密码
        this.userService.modifySelfPwd(dto);
        return AjaxResponse.success().message("修改成功");
    }

}
